<script setup>
import {useRouter} from 'vue-router'
import {ref, reactive, onMounted, nextTick, h, computed} from 'vue'
import {
  httpCreateApp,
  httpDeleteApp,
  httpAppList,
  httpAppCategories,
  httpCollectApp,
  httpApply
} from '@/api/application.js'
import {ElForm, ElLoading, ElMessage, ElMessageBox, ElSelect, ElOption} from 'element-plus'
import Pagination from '@/components/pagination/index.vue'
import ImageShow from '@/components/image-show/index.vue'
import useAppStore from '@/stores/application.js'
import TextAvatar from '@/components/text-avatar/index.vue'
import FireFilled from '@/icons/FireFilled.vue'

const router = useRouter()
const imagePrefix = import.meta.env.VITE_IMAGE_SUFFIX
const appStore = useAppStore()

onMounted(() => {
  getList()
  getAppCategories()
})

const query = reactive({
  classification_id: 0,
  knowledge_id: 0,
  page: 1,
  limit: 20,
  keyword: '',
  is_owner: 0
})
const appCategories = ref([])
const loading = ref(false)
const dataList = ref([])
const listTotal = ref(0)
const addShow = ref(false)
const defaultDetail = {
  title: '',
  classification_id: 0,
  knowledge_id: [],
  introduction: '',
  target: '',
  avatar: '',
  avatars: [],
  is_recommend: 0,
  option_message: [],
  character: '',
  demand: '',
  weight: 0
}
const rules = {
  title: [{required: true, message: '请填写应用名称', trigger: 'blur'}],
  introduction: [{required: true, message: '请填写应用描述', trigger: 'blur'}],
  // avatars: [{required: true, message: '请上传应用图片', trigger: 'change'}],
  character: [{required: true, message: '请输入应用指令', trigger: 'blur'}]
}
const detail = reactive({...defaultDetail})
const addLoading = ref(false)
/**
 * @type {Ref<ElForm>}
 */
const submitForm = ref(null)

const handleFilter = () => {
  query.page = 1
  getList()
}

const getAppCategories = async () => {
  const res = await httpAppCategories({limit: 99}).catch(() => null)
  if (!res) return
  const {list} = res
  appCategories.value = [
    {id: 0, name: '全部'},
    {id: -1, name: '我的应用'},
    {id: -2, name: '收藏应用'}
  ].concat(list)
}

const handleSelectAppCategory = (id) => {
  if (id === query.classification_id) {
    return
  }
  if (id === -1 || id === -2) {
    query.is_owner = Math.abs(id)
  } else {
    query.is_owner = 0
  }
  query.classification_id = id
  handleFilter()
}

const getList = async () => {
  loading.value = true
  const query_data = {...query}
  if (query_data.classification_id < 0) {
    query_data.classification_id = 0
  }
  const response = await httpAppList(query_data).catch(() => null)
  loading.value = false
  if (!response) return
  const {list, total} = response
  dataList.value = list
  listTotal.value = total
}

const handleAdd = () => {
  Object.keys(defaultDetail).forEach(key => {
    detail[key] = defaultDetail[key]
  })
  addShow.value = true
  nextTick(() => {
    submitForm.value.clearValidate && submitForm.value.clearValidate()
  })
}

const handleUpdate = (item) => {
  Object.keys(defaultDetail).forEach(key => {
    detail[key] = item[key]
  })
  detail.avatars = [item.avatar]
  detail.application_id = item.id
  detail.knowledge_id = JSON.parse(detail.knowledge_id)
  detail.option_message = JSON.parse(detail.option_message)
  addShow.value = true
  nextTick(() => {
    submitForm.value.clearValidate && submitForm.value.clearValidate()
  })
}

const handleSubmit = async () => {
  const valid = await submitForm.value.validate(valid => valid)
  if (!valid) return
  addLoading.value = true
  const submitData = {...detail}
  submitData.avatar = submitData.avatars.length ? submitData.avatars[0] : ''
  delete submitData.avatars
  const response = await httpCreateApp(submitData).catch(() => null)
  addLoading.value = false
  if (!response) return
  addShow.value = false
  ElMessage.success('新增成功')
  query.classification_id = -1
  handleFilter()
}


const handleDelete = async (id) => {
  const confirm = await ElMessageBox.confirm('删除后无法恢复，确认删除此应用？', '确认提示', {
    confirmButtonText: '确认删除',
    cancelButtonText: '再想想'
  }).then(() => true).catch(() => false)
  if (!confirm) return
  const load = ElLoading.service({fullscreen: true, text: '努力加载中...'})
  const res = await httpDeleteApp(id).catch(() => null)
  load.close()
  if (res) {
    ElMessage.success('删除成功')
  }
  await getList()
}

let likeTimer = null

const likeApp = (item) => {
  if (likeTimer) {
    clearTimeout(likeTimer)
  }
  likeTimer = setTimeout(() => {
    item.is_collect = item.is_collect === 0 ? 1 : 0
    httpCollectApp(item.id).catch(() => {
      item.is_collect = item.is_collect === 0 ? 1 : 0
    })
    likeTimer = null
  }, 500)
}

const useApp = (item) => {
  const itemNew = {...item}
  itemNew.option_message = JSON.parse(itemNew.option_message)
  appStore.setUseApp(itemNew)
  router.push('/chat?add=1')
}

const el_options = computed(() => {
  const options = []
  appCategories.value.forEach(cate => {
    const { id, name } = cate
    if (id > 0) {
      options.push({
        value: id,
        label: name,
        key: id
      })
    }
  })
  return options
})

const applyCategory = ref(null)
const applyApplication = (item) => {
  ElMessageBox({
    title: '请选择分类',
    showCancelButton: true,
    message: () => h(ElSelect, {
      modelValue: applyCategory.value,
      clearable: true,
      placeholder: '请选择分类',
      style: 'width:390px',
      'onUpdate:modelValue': (val) => {
        applyCategory.value = val
      }
    }, {
      default: () => el_options.value.map(option => h(ElOption, {...option}))
    })
  }).then(() => {
    if (!applyCategory.value) {
      ElMessage.warning('请选择分类')
      return
    }
    const load = ElLoading.service({fullscreen: true})
    httpApply({
      application_id: item.id,
      category_id: applyCategory.value
    }).then(() => {
      load.close()
      item.release_status = 1
      ElMessage.success('发布申请成功，请等待审核！')
    }).catch(() => {
      load.close()
    })
  }).catch(() => {
  })
}

</script>

<template>
  <div class="pw-100 vh-100 knowledge-bg knowledge-mem">
    <div>
      <el-input
          prefix-icon="Search"
          v-model="query.keyword"
          @keyup.native.enter="handleFilter"
          maxlength="32"
          clearable
          placeholder="搜索应用"
          class="w-300 margin-left-10"
      />
      <el-button class="margin-left-10" icon="Search" type="primary" @click="handleFilter">搜索</el-button>
      <el-button class="margin-left-10" icon="CirclePlus" type="warning" @click="handleAdd">添加我的应用</el-button>
    </div>
    <div class="app-categories margin-top-20 margin-left-10">
      <el-button v-for="item in appCategories" :type="item.id === query.classification_id ? 'primary' : ''"
                 @click="handleSelectAppCategory(item.id)">{{ item.name }}
      </el-button>
    </div>
    <div v-loading="loading" class="padding-10 knowledge-box">
      <el-row :gutter="20" v-if="dataList.length">
        <el-col
            v-for="(item, index) in dataList"
            :key="index"
            :xs="12"
            :sm="12"
            :md="8"
            :lg="8"
            :xl="6"
        >
          <div class="flex justify-content-center item-kno border-radius margin-bottom-20 padding-15">
            <div class="w-60 text-center">
              <el-image
                  fit="cover"
                  :src="imagePrefix + item.avatar"
                  :preview-src-list="[imagePrefix + item.avatar]"
                  :initial-index="index"
                  class="w-60 h-60 border-radius-s"
              >
                <template #error>
                  <text-avatar :text="item.title" :width="60" style="border-radius: 4px"/>
                </template>
              </el-image>
            </div>
            <div class="knowledge-info pointer" @click="useApp(item)">
              <div class="multi-line-text title" :title="item.title">
                <el-text class="font-size-2xl font-bold">{{ item.title }}</el-text>
              </div>
              <el-tooltip
                  effect="dark"
              >
                <template #content>
                  <div style="max-width: 400px;">{{ item.introduction }}</div>
                </template>
                <div class="description flex align-items-center">
                  <div class="multi-line-text line-clamp-2">
                    <el-text>{{ item.introduction }}</el-text>
                  </div>
                </div>
              </el-tooltip>
              <div class="flex h-20 align-items-center" v-if="query.classification_id !== -1 && !loading">
                <el-icon class="font-size-l" style="color: var(--el-color-danger)">
                  <FireFilled/>
                </el-icon>
                <span class="margin-left-5 margin-right-30 line-height margin-top-2">{{ item.click_number }}</span>
                <el-tooltip effect="dark" content="收藏" placement="top" v-if="!item.is_collect">
                  <el-icon class="font-size-xl" @click.stop="likeApp(item)">
                    <component is="Star"/>
                  </el-icon>
                </el-tooltip>
                <el-tooltip effect="dark" content="取消收藏" placement="top" v-else>
                  <el-icon class="font-size-3xl" style="color: var(--el-color-danger)" @click.stop="likeApp(item)">
                    <component is="StarFilled"/>
                  </el-icon>
                </el-tooltip>
              </div>
              <div class="flex h-20 align-items-center justify-content-right"
                   v-if="query.classification_id === -1 && !loading">
                <el-button type="primary" icon="Promotion" plain text
                           v-if="item.release_status === 0 || item.release_status === 4"
                           @click.stop="applyApplication(item)"
                >发布
                </el-button>
                <el-button type="warning" icon="Promotion" plain text
                           v-if="item.release_status === 1"
                           @click.stop="() => {}"
                >审核中
                </el-button>
                <el-button type="success" icon="Promotion" plain text
                           v-if="item.release_status === 2"
                           @click.stop="() => {}"
                >已发布
                </el-button>
                <el-popover
                  placement="top-start"
                  title="失败原因"
                  :width="200"
                  trigger="click"
                >
                  <template #default>
                    <div class="flex justify-content-center">
                      <span>{{item.fail_reason}}</span>
                    </div>
                  </template>
                  <template #reference>
                    <el-button type="danger" icon="Promotion" plain text
                               v-if="item.release_status === 3"
                               @click.stop="() => {}"
                    >发布失败
                    </el-button>
                  </template>
                </el-popover>
              </div>
            </div>
            <div
                class="collection delete"
                @click.stop="handleDelete(item.id)"
                v-if="query.classification_id === -1 && !loading && item.release_status !== 1"
            >
              <el-icon>
                <component is="Delete"></component>
              </el-icon>
            </div>
            <!--            <div
                            class="collection"
                            :class="item.is_collect ? 'delete font-size-2xl' : 'info'"
                            @click.stop="likeApp(item)"
                            v-if="query.classification_id !== -1 && !loading"
                        >
                          <el-icon>
                            <component :is="item.is_collect ? 'StarFilled' : 'Star'"></component>
                          </el-icon>
                        </div>-->
            <div
                class="collection"
                @click.stop="handleUpdate(item)"
                v-if="query.classification_id === -1 && !loading && item.release_status !== 1"
            >
              <el-icon>
                <component is="Edit"></component>
              </el-icon>
            </div>
          </div>
        </el-col>
      </el-row>
      <el-empty description="暂无应用" v-else/>
      <pagination
          :total="listTotal"
          v-model:page="query.page"
          v-model:limit="query.limit"
          @pagination="getList"
      />
    </div>
  </div>
  <el-dialog
      v-model="addShow"
      :close-on-click-modal="false"
      :title="`${detail.id ? '编辑' : '新增'}个人应用`"
      width="650px"
      top="10vh"
      draggable
      center
  >
    <el-form label-width="150" :rules="rules" :model="detail" ref="submitForm">
      <el-form-item
          label="应用名称："
          prop="title"
      >
        <el-input
            v-model="detail.title"
            maxlength="50"
            class="w-400"
            clearable
            placeholder="输入应用名称，例如：翻译助手"
        />
      </el-form-item>
      <el-form-item
          label="应用简介："
          prop="introduction"
      >
        <el-input
            v-model="detail.introduction" maxlength="500" class="w-400" clearable
            placeholder="输入知识库简介（例如：我能进行中英文互译，及将中文翻译为英文，英文翻译为中文）"
            type="textarea" :rows="4" resize="none" show-word-limit
        />
      </el-form-item>
      <el-form-item
          label="应用图片："
          prop="avatars"
      >
        <image-show
            v-model:list="detail.avatars"
            :limit="1"
            :show-drag="false"
        />
      </el-form-item>
      <el-form-item
          label="应用指令："
          prop="character"
      >
        <el-input
            v-model="detail.character" maxlength="1000" class="w-400" clearable
            placeholder="输入应用指令（例如：你是一个翻译专家。如果输入内容为英文，请翻译为中文，如果用户输入内容为中文，请翻译为英文。只需要回复译文即可。）"
            type="textarea" :rows="6" resize="none" show-word-limit
        />
        <el-text type="info">
          应用指令是发送指令给AI模型，能指导AI模型的输出行为，确保AI模型能够按照用户的意图和需求进行响应
        </el-text>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="primary" @click="handleSubmit()" :loading="addLoading">提 交</el-button>
      <el-button type="warning" @click="addShow=false" :loading="addLoading">取 消</el-button>
    </template>
  </el-dialog>
</template>
<style scoped lang="scss">
.knowledge-bg {
  background-color: var(--el-bg-color);
  position: absolute;
  left: 0;
  top: 0;
  padding: 20px;
}

.item-kno {
  background: var(--el-bg-color);
  transition: color 0.2s, background-color 0.2s;
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.24);
  position: relative;
}

.dark {
  .item-kno {
    background: var(--el-color-info-light-9);
    box-shadow: var(--el-box-shadow-lighter);
  }
}

.knowledge-box {
  margin-top: 10px;
  overflow-y: auto;
  overflow-x: hidden;
  height: calc(100vh - 75px);
}

.knowledge-mem {

  .knowledge-info {
    width: calc(100% - 50px);
    padding-left: 12px;

    .description {
      height: 50px;
      overflow: hidden;

      .desc-b {
        max-height: 48px;
        display: -webkit-box;
        overflow: hidden;
        text-overflow: ellipsis;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
      }
    }

    .title {
      width: calc(100% - 60px);
    }
  }

  .collection {
    width: 20px;
    height: 20px;
    position: absolute;
    right: 30px;
    top: 10px;
    font-size: 16px;
    cursor: pointer;
    color: var(--el-color-primary);

    &.info {
      color: var(--el-color-info);
      right: 8px;
    }

    &.delete {
      color: var(--el-color-danger);
      right: 8px;

      i {
        top: -1px;
      }
    }
  }
}
</style>